package com.du.web.sample.util.water.wrap;

import com.microsoft.schemas.office.office.CTLock;
import com.microsoft.schemas.office.office.STConnectType;
import com.microsoft.schemas.vml.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.util.Iterator;

/**
 * @desc: XWPFHeaderFooterPolicy 包装类
 * <p>重写了方法 createWatermark</p>
 * @see XWPFHeaderFooterPolicy
 * @author: shuangdu
 * @date: 2021/9/17
 * @since: 1.8
 */
public class HeaderFooterPolicyWrap {

    public static final STHdrFtr.Enum DEFAULT;
    public static final STHdrFtr.Enum EVEN;
    public static final STHdrFtr.Enum FIRST;

    static {
        DEFAULT = STHdrFtr.DEFAULT;
        EVEN = STHdrFtr.EVEN;
        FIRST = STHdrFtr.FIRST;
    }

    private XWPFHeaderFooterPolicy headerFooterPolicy;
    private  XWPFDocument doc;
    private XWPFHeader firstPageHeader;
    private XWPFFooter firstPageFooter;
    private XWPFHeader evenPageHeader;
    private XWPFFooter evenPageFooter;
    private XWPFHeader defaultHeader;
    private XWPFFooter defaultFooter;

    public HeaderFooterPolicyWrap(XWPFDocument doc, XWPFHeaderFooterPolicy headerFooterPolicy) {
        this.doc = doc;
        this.headerFooterPolicy = headerFooterPolicy;
    }

    public XWPFHeader getHeader(STHdrFtr.Enum type) {
        if (type == STHdrFtr.EVEN) {
            return this.evenPageHeader;
        } else {
            return type == STHdrFtr.FIRST ? this.firstPageHeader : this.defaultHeader;
        }
    }

    private int getRelationIndex(XWPFRelation relation) {
        int i = 1;
        Iterator var3 = this.doc.getRelationParts().iterator();

        while(var3.hasNext()) {
            POIXMLDocumentPart.RelationPart rp = (POIXMLDocumentPart.RelationPart)var3.next();
            if (rp.getRelationship().getRelationshipType().equals(relation.getRelation())) {
                ++i;
            }
        }

        return i;
    }

    public XWPFHeader createHeader(STHdrFtr.Enum type, XWPFParagraph[] pars) {
        XWPFHeader header = this.getHeader(type);
        if (header == null) {
            HdrDocument hdrDoc = HdrDocument.Factory.newInstance();
            XWPFRelation relation = XWPFRelation.HEADER;
            int i = this.getRelationIndex(relation);
            XWPFHeader wrapper = (XWPFHeader)this.doc.createRelationship(relation, XWPFFactory.getInstance(), i);
            wrapper.setXWPFDocument(this.doc);
            CTHdrFtr hdr = this.buildHdr(type, wrapper, pars);
            wrapper.setHeaderFooter(hdr);
            hdrDoc.setHdr(hdr);
            this.assignHeader(wrapper, type);
            header = wrapper;
        }

        return header;
    }

    private void assignHeader(XWPFHeader hdr, STHdrFtr.Enum type) {
        if (type == STHdrFtr.FIRST) {
            this.firstPageHeader = hdr;
        } else if (type == STHdrFtr.EVEN) {
            this.evenPageHeader = hdr;
        } else {
            this.defaultHeader = hdr;
        }

    }

    private CTHdrFtr buildHdrFtr(XWPFParagraph[] paragraphs, XWPFHeaderFooter wrapper) {
        CTHdrFtr ftr = wrapper._getHdrFtr();
        if (paragraphs != null) {
            for(int i = 0; i < paragraphs.length; ++i) {
                ftr.addNewP();
                ftr.setPArray(i, paragraphs[i].getCTP());
            }
        }

        return ftr;
    }

    private CTHdrFtr buildHdr(STHdrFtr.Enum type, XWPFHeaderFooter wrapper, XWPFParagraph[] pars) {
        CTHdrFtr hdr = this.buildHdrFtr(pars, wrapper);
        this.setHeaderReference(type, wrapper);
        return hdr;
    }

    private void setHeaderReference(STHdrFtr.Enum type, XWPFHeaderFooter wrapper) {
        CTHdrFtrRef ref = this.doc.getDocument().getBody().getSectPr().addNewHeaderReference();
        ref.setType(type);
        ref.setId(this.doc.getRelationId(wrapper));
    }


    public void createWatermark(String text) {
        XWPFParagraph[] pars = new XWPFParagraph[]{this.getWatermarkParagraph(text, 1)};
        this.createHeader(DEFAULT, pars);
        pars[0] = this.getWatermarkParagraph(text, 2);
        this.createHeader(FIRST, pars);
        pars[0] = this.getWatermarkParagraph(text, 3);
        this.createHeader(EVEN, pars);
    }

    /**
     * 重写方法
     * @param text
     * @param idx
     * @return
     */
    public XWPFParagraph getWatermarkParagraph(String text, int idx) {
        CTP p = org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP.Factory.newInstance();
        byte[] rsIdr = this.doc.getDocument().getBody().getPArray(0).getRsidR();
        byte[] rsIdrDefault = this.doc.getDocument().getBody().getPArray(0).getRsidRDefault();
        p.setRsidP(rsIdr);
        p.setRsidRDefault(rsIdrDefault);
        CTPPr pPr = p.addNewPPr();
        pPr.addNewPStyle().setVal("Header");
        CTR r = p.addNewR();
        if (idx == 1) {
            //margin-left和margin-top调整位置，height和width调整大小
            //左上角
            setCTR(r, text, idx, "position:absolute;left:0pt;margin-left:-120pt;margin-top:108pt;mso-position-horizontal-relative:margin;mso-position-vertical-relative:margin;rotation:-2949120f;height:60pt;width:360pt;mso-width-relative:page;mso-height-relative:page");
            //右上角
            setCTR(r, text, idx, "position:absolute;left:0pt;margin-left:190pt;margin-top:108pt;mso-position-horizontal-relative:margin;mso-position-vertical-relative:margin;rotation:-2949120f;height:60pt;width:360pt;mso-width-relative:page;mso-height-relative:page");
            //左下角
            setCTR(r, text, idx, "position:absolute;left:0pt;margin-left:-120pt;margin-top:495pt;mso-position-horizontal-relative:margin;mso-position-vertical-relative:margin;rotation:-2949120f;height:60pt;width:360pt;mso-width-relative:page;mso-height-relative:page");
            //右下角
            setCTR(r, text, idx, "position:absolute;left:0pt;margin-left:190pt;margin-top:495pt;mso-position-horizontal-relative:margin;mso-position-vertical-relative:margin;rotation:-2949120f;height:60pt;width:360pt;mso-width-relative:page;mso-height-relative:page");
        } else {
            setCTR(r, text, idx, "position:absolute;left:0pt;mso-position-horizontal-relative:margin;mso-position-vertical-relative:margin;rotation:-2949120f;height:60pt;width:360pt;mso-width-relative:page;mso-height-relative:page");
        }
        return new XWPFParagraph(p, this.doc);
    }

    /**
     * 添加水印
     * @param r
     * @param text
     * @param idx
     * @param style
     */
    private void setCTR(CTR r, String text, int idx, String style) {
        CTRPr rPr = r.addNewRPr();
        rPr.addNewNoProof();
        CTPicture pict = r.addNewPict();
        CTGroup group = com.microsoft.schemas.vml.CTGroup.Factory.newInstance();
        CTShapetype shapeType = group.addNewShapetype();
        shapeType.setId("_x0000_t136");
        shapeType.setCoordsize("1600,21600");
        shapeType.setSpt(136.0F);
        shapeType.setAdj("10800");
        shapeType.setPath2("m@7,0l@8,0m@5,21600l@6,21600e");
        CTFormulas formulas = shapeType.addNewFormulas();
        formulas.addNewF().setEqn("sum #0 0 10800");
        formulas.addNewF().setEqn("prod #0 2 1");
        formulas.addNewF().setEqn("sum 21600 0 @1");
        formulas.addNewF().setEqn("sum 0 0 @2");
        formulas.addNewF().setEqn("sum 21600 0 @3");
        formulas.addNewF().setEqn("if @0 @3 0");
        formulas.addNewF().setEqn("if @0 21600 @1");
        formulas.addNewF().setEqn("if @0 0 @2");
        formulas.addNewF().setEqn("if @0 @4 21600");
        formulas.addNewF().setEqn("mid @5 @6");
        formulas.addNewF().setEqn("mid @8 @5");
        formulas.addNewF().setEqn("mid @7 @8");
        formulas.addNewF().setEqn("mid @6 @7");
        formulas.addNewF().setEqn("sum @6 0 @5");
        CTPath path = shapeType.addNewPath();
        path.setTextpathok(STTrueFalse.T);
        path.setConnecttype(STConnectType.CUSTOM);
        path.setConnectlocs("@9,0;@10,10800;@11,21600;@12,10800");
        path.setConnectangles("270,180,90,0");
        CTTextPath shapeTypeTextPath = shapeType.addNewTextpath();
        shapeTypeTextPath.setOn(STTrueFalse.T);
        shapeTypeTextPath.setFitshape(STTrueFalse.T);
        CTHandles handles = shapeType.addNewHandles();
        CTH h = handles.addNewH();
        h.setPosition("#0,bottomRight");
        h.setXrange("6629,14971");
        CTLock lock = shapeType.addNewLock();
        lock.setExt(STExt.EDIT);
        CTShape shape = group.addNewShape();
        shape.setId("PowerPlusWaterMarkObject" + idx);
        shape.setSpid("_x0000_s102" + (4 + idx));
        shape.setType("#_x0000_t136");
        // 设置形状样式（旋转，位置，相对路径等参数）
        shape.setStyle(style);
        shape.setWrapcoords("616 5068 390 16297 39 16921 -39 17155 7265 17545 7186 17467 -39 17467 18904 17467 10507 17467 8710 17545 18904 17077 18787 16843 18358 16297 18279 12554 19178 12476 20701 11774 20779 11228 21131 10059 21248 8811 21248 7563 20975 6316 20935 5380 19490 5146 14022 5068 2616 5068");
        // 添加水印颜色
        shape.setFillcolor("#D3D3D3");
        // 字体设置为实心
        shape.setStroked(STTrueFalse.FALSE);
        // 绘制文本的路径
        CTTextPath shapeTextPath = shape.addNewTextpath();
        // 设置字体与大小 1pt为自动大小
        shapeTextPath.setStyle("font-family:Consolas;font-size:1pt");
        shapeTextPath.setString(text);
        pict.set(group);
    }

}
